package psl;

import java.io.InputStream;
import java.io.PrintStream;

public class Encryptor
{
    private byte mbState[];
    private int miX;
    private int miY;

    public Encryptor ()
    {
        mbState = new byte[256];
    }

    public static String encrypt (String fsData, String fsKey)
    {
        Encryptor loEncryptor = new Encryptor ();
        loEncryptor.setKey (fsKey.getBytes ());
        byte laData[] = fsData.getBytes ();
        System.out.println ("laData: " + laData);
        loEncryptor.encrypt (laData);
        char lcData[] = (new String (laData)).toCharArray ();
        StringBuffer loBuffer = new StringBuffer ();
        for (int liCtr = 0; liCtr < laData.length; liCtr++)
        {
            String lsHex = Integer.toHexString (lcData[liCtr]);
            if (lsHex.length () < 2)
            {
                loBuffer.append ('0');
            }
            loBuffer.append (lsHex);
        }

        return loBuffer.toString ();
    }

    public static String decrypt (String fsData, String fsKey)
    {
        char lcData[] = fsData.toCharArray ();
        StringBuffer loBuffer = new StringBuffer ();
        for (int liCtr = 0; liCtr < lcData.length; liCtr += 2)
        {
            String lsHex = "#" + fsData.substring (liCtr, liCtr + 2);
            char lcChar = (char) Integer.decode (lsHex).intValue ();
            loBuffer.append (lcChar);
        }

        byte laData[] = loBuffer.toString ().getBytes ();
        Encryptor loEncryptor = new Encryptor ();
        loEncryptor.setKey (fsKey.getBytes ());
        loEncryptor.encrypt (laData);
        return new String (laData);
    }

    public void setKey (byte fbKey[])
    {
        int liIndex1 = 0;
        int liIndex2 = 0;
        miX = 0;
        miY = 0;
        for (int liCtr = 0; liCtr < 256; liCtr++)
        {
            mbState[liCtr] = (byte) liCtr;
        }

        for (int liCtr = 0; liCtr < 256; liCtr++)
        {
            liIndex2 = fbKey[liIndex1] + mbState[liCtr] + liIndex2 & 0xff;
            byte lbTemp = mbState[liCtr];
            mbState[liCtr] = mbState[liIndex2];
            mbState[liIndex2] = lbTemp;
            liIndex1 = ++liIndex1 % fbKey.length;
        }
    }

    public void encrypt (byte fbDataIn[], int fiOffset, int fiLength, byte fbDataOut[])
    {
        int liLength = fiLength + fiOffset;
        for (int liCtr = fiOffset; liCtr < liLength; liCtr++)
        {
            miX = miX + 1 & 0xff;
            miY = mbState[miX] + miY & 0xff;
            byte lbTemp = mbState[miX];
            mbState[miX] = mbState[miY];
            mbState[miY] = lbTemp;
            fbDataOut[liCtr] = (byte) (fbDataIn[liCtr] ^ mbState[mbState[miX] + mbState[miY] & 0xff]);
        }

    }

    public void encrypt (byte fbData[], int fiOffset, int fiLength)
    {
        encrypt (fbData, fiOffset, fiLength, fbData);
    }

    public void encrypt (byte fbDataIn[], byte fbDataOut[])
    {
        encrypt (fbDataIn, 0, fbDataIn.length, fbDataOut);
    }

    public void encrypt (byte fbData[])
    {
        encrypt (fbData, 0, fbData.length, fbData);
    }

/*
    public static void main(String args[])
        throws Exception
    {
        String lsKey = "mbczljgda";
        System.out.println("Enter Data: ");
        byte laRead[] = new byte[255];
        int liSize = System.in.read(laRead);
        String lsData = new String(laRead, 0, liSize - 1);
        String lsEncrypt = encrypt(lsData, lsKey);
        String lsDecrypt = decrypt(lsEncrypt, lsKey);
        System.out.println("Original: " + lsData + " Encrypted: " + lsEncrypt + " Decrypted: " + lsDecrypt);
    }
*/

}
